module	sdram_addr_test(
			sclk,
			resetb,
			test_start,
			r_data,
			test_end,
			unmatch,
			sdram_cnt,
			sdram_addr,
			sdram_bank,
			sdram_oeb,
			w_data,
			unmatch_tmp,
			work_on);
			
parameter	Sdram_A_Width=13;
parameter	Sdram_D_Width=32;
parameter	Sdram_C_Width=4;
parameter	Input_delay=1;
parameter	Output_delay=1;	
parameter	Optional_time=4;

parameter	base_length=8+Input_delay+Output_delay+Optional_time;
parameter	cycle_length=(Sdram_A_Width+1)*2-1;
parameter	cycle_write=Sdram_A_Width;		
			
input		sclk;
input		resetb;
		
input		test_start;
input	[Sdram_D_Width-1:0]	r_data;

output		test_end;
output		unmatch;
output		unmatch_tmp;
output		work_on;

output	[4:0]	sdram_cnt;
output	[1:0]	sdram_bank;
output		sdram_oeb;
output	[Sdram_A_Width-2-1:0]	sdram_addr;
output	[Sdram_D_Width-1:0]	w_data;

reg		test_end;
reg		unmatch;
reg	[1:0]	sdram_bank;
reg		sdram_oeb;
reg	[Sdram_A_Width-2-1:0]	sdram_addr;
reg	[Sdram_D_Width-1:0]	w_data;

reg	[6:0]	base_count;
reg	[6:0]	cycle_count;
reg		base_end;
reg		cycle_end;
reg		cycle_read;
reg		work_on;
reg		work_on_last;
reg		test_start_last;
reg	[Sdram_A_Width-1:0]	test_flag;
reg	[4:0]	ta_cmd;
wire	[1:0]	ta_bank;
wire	[Sdram_A_Width-2-1:0]	ta_row;




parameter	Mode_Reg_Set	=5'b00000;			//0
parameter	Auto_Refresh	=5'b00010;			//2
parameter	Row_Active	=5'b00110;			//6
parameter	Pre_Charge	=5'b00100;			//4
parameter	PreCharge_All	=5'b00101;			//5
parameter	Write		=5'b01000;			//8
parameter	Write_Pre	=5'b01001;			//9
parameter	Read		=5'b01010;			//10
parameter	Read_Pre	=5'b01011;			//11
parameter	Nop		=5'b01110;			//14
parameter	Dsel		=5'b11110;			//30	


always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		test_start_last<=0;
	else
		test_start_last<=test_start;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)	
		work_on<=0;
	else if (test_start==0 && test_start_last==1)
		work_on<=1;
	else if (cycle_end==1 && base_end==1)
		work_on<=0;
		
always @(posedge sclk or negedge resetb)
	if (resetb==0)
		work_on_last<=0;
	else
		work_on_last<=work_on;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		test_end<=0;
	else if (work_on==0 && work_on_last==1)
		test_end<=1;
	else
		test_end<=0;							
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		base_count<=0;
	else if (work_on==0 || base_end==1)
		base_count<=0;
	else
		base_count<=base_count+1;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		base_end<=0;
	else if (base_count==base_length)
		base_end<=1;
	else
		base_end<=0;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		cycle_count<=0;
	else if (work_on==0)
		cycle_count<=0;
	else if (base_end==1)
		cycle_count<=cycle_count+1;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		cycle_read<=0;
	else if (cycle_count==cycle_write)
		cycle_read<=1;
	else
		cycle_read<=0;				
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		cycle_end<=0;
	else if (cycle_count==cycle_length)
		cycle_end<=1;
	else
		cycle_end<=0;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		test_flag<=1;
	else if (base_end==1 && cycle_read==1)
		test_flag<=1;
	else if (base_end==1 && cycle_end==1)
		test_flag<=1;	
	else if (base_end==1)
		test_flag<={test_flag[Sdram_A_Width-2:0],1'b0};
		
assign	ta_row=test_flag[Sdram_A_Width-1:2];
assign	ta_bank=test_flag[1:0];
assign	sdram_cnt[4]=1;
assign	sdram_cnt[3:0]=ta_cmd[4:1];



always @(posedge sclk or negedge resetb)
	if (resetb==0)
		ta_cmd<=Nop;
//	else if (cycle_count<15)
	else if (cycle_count<Sdram_A_Width+1)
		case (base_count)
			7'h02:		ta_cmd<=Row_Active;
			7'h05:		ta_cmd<=Write;
			7'h08:		ta_cmd<=Pre_Charge;
			default:	ta_cmd<=Nop;
		endcase
	else 
		case (base_count)
			7'h02:		ta_cmd<=Row_Active;
			7'h05:		ta_cmd<=Read;
			7'h08:		ta_cmd<=Pre_Charge;
			default:	ta_cmd<=Nop;
		endcase
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		sdram_addr<=0;
	else
		case(base_count)
			7'h02:		sdram_addr<=ta_row;
			default:	sdram_addr<=0;
		endcase
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		sdram_bank<=0;
	else
		case(base_count)
			7'h02:		sdram_bank<=ta_bank;
			7'h05:		sdram_bank<=ta_bank;
			7'h08:		sdram_bank<=ta_bank;
			default:	sdram_bank<=0;
		endcase
/*		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		sdram_oeb<=0;
//	else if (cycle_count<15)
	else if (cycle_count<Sdram_A_Width+1)
		case(base_count)
			7'h04:		sdram_oeb<=1;
			default:	sdram_oeb<=0;
		endcase	
	else
		sdram_oeb<=0;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		w_data<=0;
//	else if (cycle_count<15)
	else if (cycle_count<Sdram_A_Width+1)
		case(base_count)
			7'h04:		w_data<=cycle_count+1;
			default:	w_data<=0;
		endcase				
*/
always	@(posedge sclk)
	if (cycle_count<Sdram_A_Width+1)
		sdram_oeb<=1;
	else
		sdram_oeb<=0;

//always	@(posedge sclk)
//	w_data<=cycle_count+1;

always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		w_data<=0;
	else
		case(base_count)
			7'h05:		w_data<=cycle_count+1;
			default:	w_data<=0;
		endcase
		
//always @(posedge sclk or negedge resetb)
//always	@(negedge sclk or negedge resetb)
//	if (resetb==0)
//		unmatch<=0;
//	else if (cycle_count>Sdram_A_Width && base_count==8+Input_delay+Output_delay)
//	else if (cycle_count>Sdram_A_Width && base_count==8+Input_delay+Output_delay)
//	begin
//		if(r_data!==cycle_count-Sdram_A_Width)
//			unmatch<=1;
//		else
//			unmatch<=0;
//	end		
//	else
//		unmatch<=0;
		
		
		
reg		flag_comp1,flag_comp2,unmatch_tmp1,unmatch_tmp2;
reg	[7:0]	value_l;
reg		value_h_last;
wire		value_h;
reg		unmatch_tmp;
assign		value_h=(~r_data[31])&(~r_data[30])&(~r_data[29])&(~r_data[28])&(~r_data[27])&(~r_data[26])&(~r_data[25])&(~r_data[24])&(~r_data[23])&(~r_data[22])&(~r_data[21])&(~r_data[20])&(~r_data[19])&(~r_data[18])&(~r_data[17])&(~r_data[16])&(~r_data[15])&(~r_data[14])&(~r_data[13])&(~r_data[12])&(~r_data[11])&(~r_data[10])&(~r_data[9])&(~r_data[8]);	

always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		flag_comp1<=0;
	else if (cycle_read==1 && base_end==1)
		flag_comp1<=1;
	else if (work_on==0)
		flag_comp1<=0;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		flag_comp2<=0;
	else if (base_count==(8+Input_delay+Output_delay+1))
		flag_comp2<=1;
	else
		flag_comp2<=0;
		
always	@(posedge sclk)
	value_l<=cycle_count-Sdram_A_Width;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		unmatch_tmp<=0;
	else if (r_data=={24'h0,value_l})
		unmatch_tmp<=0;
	else 
		unmatch_tmp<=1;
		
//always	@(posedge sclk or negedge resetb)
//	if (resetb==0)
//		unmatch_tmp<=0;
////	else if (r_data==cycle_count-Sdram_A_Width)
//	else if (r_data[7:0]==value_l && value_h==1)
//		unmatch_tmp<=0;
//	else
//		unmatch_tmp<=1;

always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		unmatch<=0;
	else if (flag_comp1==1 && flag_comp2==1)
		unmatch<=unmatch_tmp;
	else
		unmatch<=0;
																
				
endmodule					
					
									
									
				
						
						
														
		
					
		
					